#include "ManejadorBits.h"
#include "vector_binario.h"
#include "codigos.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

/* ******************************************************************
 *                        PRUEBAS UNITARIAS							*
 * *****************************************************************/
 
void print_test(char* name, bool result) {
    printf("%s: %s\n", name, result? "OK" : "ERROR");
}

// Imprime bits
void Print_Binario(char x){
	int count;
	for (count=0; count < 8; count++){	
			if ( x & 128){
				printf("1");
			}	
			else printf("0");
			x<<= 1;
	}
	printf("-"); //marca el octeto;
}

/* Prueba que las primitivas del vector funcionen correctamente. */
void prueba_ManejadorBits( char* ruta) {
    
    //char* ruta = "/home/nicolas/TpDatos/tp-datos-1c-2013/Codigo/pruebaBits.dat";
    //char* ruta = "/home/maxi/Desktop/tp-datos-1c-2013/Codigo/pruebaBits.dat";
    
    ManejadorBits_t* manejador = ManejadorBits_crear (ruta, true);
    
    print_test("Pruebo que el buffer esta vacio ", ManejadorBits_buffer_esta_vacio (manejador) );
	
	print_test("Pruebo que esta en modo escritura ", ManejadorBits_es_modo_escritura (manejador) );
	
	int numero = 5;
	
	vector_binario_t* vector = cod_unario_nuevo (numero);
	
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );
	
	print_test("Pruebo que el buffer no esta vacio ", !ManejadorBits_buffer_esta_vacio (manejador) );
	
	print_test("Pruebo que la cantidad e bits en el buffer es el correcto ", ManejadorBits_bits_ocupados(manejador) == 5 );			
	
	ManejadorBits_destruir (manejador);
	v_binario_destruir(vector);
	
	
	manejador = ManejadorBits_crear (ruta, false);
	
	print_test("Pruebo que esta en modo lectura ", !ManejadorBits_es_modo_escritura (manejador) ); 
	 
	print_test("Pruebo que la se carga el buffer para leer ", ManejadorBits_cargar_buffer(manejador) );
	
	char lectura = ManejadorBits_ver_buffer(manejador);
	Print_Binario(lectura);
		
	ManejadorBits_destruir (manejador);
	
}

void prueba_ManejadorBits_volumen(char* ruta) {
    
    //char* ruta = "/home/nicolas/TpDatos/tp-datos-1c-2013/Codigo/pruebaBits.dat";
    //char* ruta = "/home/maxi/Desktop/tp-datos-1c-2013/Codigo/pruebaBits.dat";
    
    ManejadorBits_t* manejador = ManejadorBits_crear (ruta, true);
    
   	int numero = 1;
	
	vector_binario_t* vector = cod_unario_nuevo (numero);
		
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );
	v_binario_destruir(vector);
	
	vector = cod_unario_nuevo (9);	
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );
	v_binario_destruir(vector);
	
	vector = cod_unario_nuevo (3);	
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );
	v_binario_destruir(vector);
	
	char* ab = "abcd";
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_cadena(manejador,ab) );

	
	vector = cod_unario_nuevo (13);
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );
	v_binario_destruir(vector);
	
	ManejadorBits_destruir (manejador);

	
	
	manejador = ManejadorBits_crear (ruta, false);
	
	 
	print_test("Pruebo que la se carga el buffer para leer ", ManejadorBits_cargar_buffer(manejador) );
	
	char lectura = ManejadorBits_ver_buffer(manejador);
	
	Print_Binario(lectura);
	
	ManejadorBits_cargar_buffer(manejador);
	lectura = ManejadorBits_ver_buffer(manejador);
	Print_Binario(lectura);
	
	ManejadorBits_cargar_buffer(manejador);
	lectura = ManejadorBits_ver_buffer(manejador);
	Print_Binario(lectura);
	
	
	ManejadorBits_cargar_buffer(manejador);
	lectura = ManejadorBits_ver_buffer(manejador);
	Print_Binario(lectura);
	
	ManejadorBits_cargar_buffer(manejador);
	lectura = ManejadorBits_ver_buffer(manejador);
	Print_Binario(lectura);
	
	ManejadorBits_cargar_buffer(manejador);
	lectura = ManejadorBits_ver_buffer(manejador);
	Print_Binario(lectura);
	
	ManejadorBits_cargar_buffer(manejador);
	lectura = ManejadorBits_ver_buffer(manejador);
	Print_Binario(lectura);
	
	ManejadorBits_cargar_buffer(manejador);
	lectura = ManejadorBits_ver_buffer(manejador);
	Print_Binario(lectura);
	
	ManejadorBits_destruir (manejador);
	
}


void prueba_ManejadorBits_leer_unario(char* ruta){
	
	
    ManejadorBits_t* manejador = ManejadorBits_crear (ruta, true);

	int numero = 2;
	
	vector_binario_t* vector = cod_unario_nuevo (numero);	
	print_test("\nPruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );	
	v_binario_destruir(vector);
	
	vector = cod_unario_nuevo (1);	
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	vector = cod_unario_nuevo (2);	
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	ManejadorBits_destruir (manejador);
	
	manejador = ManejadorBits_crear (ruta, false);
	
	long leido = cod_unario_leer(manejador);
	
	printf ("\nEl numero es: %ld\n" , leido);
	
	leido = cod_unario_leer(manejador);
	
	printf ("\nEl numero es: %ld\n" , leido);	
	
	leido = cod_unario_leer(manejador);
	
	printf ("\nEl numero es: %ld\n" , leido);	
	
	leido = cod_unario_leer(manejador);
	
	printf ("\nEl numero es: %ld\n" , leido);	
	
	leido = cod_unario_leer(manejador);
	
	printf ("\nEl numero es: %ld\n" , leido);
	
	leido = cod_unario_leer(manejador);
	
	printf ("\nEl numero es: %ld\n" , leido);
	leido = cod_unario_leer(manejador);
	
	printf ("\nEl numero es: %ld\n" , leido);
	leido = cod_unario_leer(manejador);
	
	printf ("\nEl numero es: %ld\n" , leido);
	leido = cod_unario_leer(manejador);
	
	printf ("\nEl numero es: %ld\n" , leido);
	leido = cod_unario_leer(manejador);
	
	printf ("\nEl numero es: %ld\n" , leido);
	
	
	
	ManejadorBits_destruir (manejador);
		
	
}

void prueba_ManejadorBits_leer_Binario(char* ruta){
	
	
    ManejadorBits_t* manejador = ManejadorBits_crear (ruta, true);

	
	
	vector_binario_t* vector = cod_binario_nuevo(1 ,4);	
	print_test("\n\nPruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );	
	v_binario_destruir(vector);
	
	vector = cod_binario_nuevo(3 ,3);	
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	vector = cod_binario_nuevo(6 , 5);	
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	

	vector = cod_binario_nuevo( 13 , 4);	
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	ManejadorBits_destruir (manejador);
	
	manejador = ManejadorBits_crear (ruta, false);
	
	long leido = cod_binario_leer(manejador,4);	
	printf ("\nEl numero es: %ld\n" , leido);
	
	leido = cod_binario_leer(manejador,3);	
	printf ("\nEl numero es: %ld\n" , leido);	
	
	leido = cod_binario_leer(manejador, 5);	
	printf ("\nEl numero es: %ld\n" , leido);	
	
	leido = cod_binario_leer(manejador, 4);	
	printf ("\nEl numero es: %ld\n" , leido);
	
	//devuelve -1 pq no ahi mas nada para leer
	leido = cod_binario_leer(manejador, 3);	
	printf ("\nEl numero es: %ld\n" , leido);
	
	ManejadorBits_destruir (manejador);
		
	
}

void prueba_ManejadorBits_leer_Gamma (char* ruta) {
		
	ManejadorBits_t* manejador = ManejadorBits_crear (ruta, true);

	
	vector_binario_t* vector = cod_gamma_nuevo(9);
	print_test("\n\nPruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );	
	v_binario_destruir(vector);

	vector = cod_gamma_nuevo(1);
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	vector = cod_gamma_nuevo(5);
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	vector = cod_gamma_nuevo(3);
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	ManejadorBits_destruir (manejador);
	
	manejador = ManejadorBits_crear (ruta, false);
	
	long leido = cod_gamma_leer(manejador);	
	printf ("\nEl numero es: %ld\n" , leido);
	
	leido = cod_gamma_leer(manejador);	
	printf ("\nEl numero es: %ld\n" , leido);	
	
	leido = cod_gamma_leer(manejador);		
	printf ("\nEl numero es: %ld\n" , leido);	
	
	leido = cod_gamma_leer(manejador);	
	printf ("\nEl numero es: %ld\n" , leido);
	
	//Devuelve un 1 pq lee 0
	leido = cod_gamma_leer(manejador);	
	printf ("\nEl numero es: %ld\n" , leido);

	ManejadorBits_destruir (manejador);
		
		
}

void prueba_ManejadorBits_leer_Delta (char* ruta){
	ManejadorBits_t* manejador = ManejadorBits_crear (ruta, true);

	
	vector_binario_t* vector = cod_delta_nuevo(5);
	print_test("\n\nPruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );	
	v_binario_destruir(vector);

	vector = cod_delta_nuevo(1);
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	vector = cod_delta_nuevo(13);
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	vector = cod_delta_nuevo(8);
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	ManejadorBits_destruir (manejador);
	
	manejador = ManejadorBits_crear (ruta, false);
	
	long leido = cod_delta_leer(manejador);	
	printf ("\nEl numero es: %ld\n" , leido);
	
	leido = cod_delta_leer(manejador);	
	printf ("\nEl numero es: %ld\n" , leido);	
	
	leido = cod_delta_leer(manejador);		
	printf ("\nEl numero es: %ld\n" , leido);	
	
	leido = cod_delta_leer(manejador);	
	printf ("\nEl numero es: %ld\n" , leido);
	
	//Devuelve un 1 pq lee 0
	leido = cod_delta_leer(manejador);	
	printf ("\nEl numero es: %ld\n" , leido);

	ManejadorBits_destruir (manejador);
	
}

void prueba_ManejadorBits_leer_Caracter(char* ruta){
	
	ManejadorBits_t* manejador = ManejadorBits_crear (ruta, true);

	char* ab = "abcd";
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_cadena(manejador,ab) );

	ManejadorBits_destruir (manejador);
	
	manejador = ManejadorBits_crear (ruta, false);

	char* leido;
	int a =4;
	leido = ManejadorBits_leer_cadena (manejador,a);
	printf ("\nLa cadena es %s",leido);

	free (leido);
	ManejadorBits_destruir (manejador);
	
	
	
	
}

void prueba_ManejadorBits_leer_Lexico (char* ruta){
	
	ManejadorBits_t* manejador = ManejadorBits_crear (ruta, true);
	
	/* ESCRITURA */

	/*Repetidos*/
	vector_binario_t* vector = cod_gamma_nuevo(1);
	print_test("\n\nPruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );	
	v_binario_destruir(vector);
	
	/*Distintos*/
	vector = cod_gamma_nuevo(7);
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	/*Cadena*/
	char* ab = "valeria";
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_cadena(manejador,ab) );
	
	/*Offset*/
	vector = cod_delta_nuevo(1);
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	/*Repetidos*/
	vector = cod_gamma_nuevo(2);
	print_test("\n\nPruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );	
	v_binario_destruir(vector);
	
	/*Distintos*/
	vector = cod_gamma_nuevo(3);
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);
	
	/*Cadena*/
	ab = "mos";
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_cadena(manejador,ab) );
	
	/*Offset*/
	vector = cod_delta_nuevo(25);
	print_test("Pruebo que se puede escribir", ManejadorBits_escribir_numero (manejador, vector) );		
	v_binario_destruir(vector);

	ManejadorBits_destruir (manejador);

	/* LECTURA */
	
	manejador = ManejadorBits_crear (ruta, false);
	
	bool finalizo = false;
	while (!finalizo) {
		long repetidos = cod_gamma_leer(manejador);
		if (repetidos == -1) finalizo = true;
		if (!finalizo) printf ("\nEl repetidos es: %ld\n" , repetidos);
		
		long distintos = cod_gamma_leer(manejador);
		if (distintos == -1) finalizo = true;
		if (!finalizo) printf ("El distintos es: %ld\n" , distintos);
		
		char* cadena = ManejadorBits_leer_cadena (manejador , distintos);
		if (!cadena) finalizo = true;
		if (!finalizo) printf ("La cadena es: %s\n", cadena);
		
		free(cadena);

		long offset = cod_delta_leer(manejador);
		if (offset == -1) finalizo = true;
		if (!finalizo) printf ("El offset es: %ld\n" , offset);
	}
	
	
	/*
	repetidos = cod_gamma_leer(manejador);	
	printf ("\nEl repetidos es: %ld\n" , repetidos);
	
	distintos = cod_gamma_leer(manejador);	
	printf ("El distintos es: %ld\n" , distintos);
	
	cadena = ManejadorBits_leer_cadena (manejador , distintos);
	printf ("La cadena es: %s\n", cadena);
	
	free(cadena);

	offset = cod_delta_leer(manejador);	
	printf ("El offset es: %ld\n" , offset);
	
	*/
	ManejadorBits_destruir (manejador);
	
}



/* ******************************************************************
 *                        PROGRAMA PRINCIPAL
 * *****************************************************************/

/* Programa principal. */
int main(void) {

	 //char* ruta = "/home/nicolas/TpDatos/tp-datos-1c-2013/Codigo/pruebaBits.dat";
    char* ruta = "pruebaBits.dat";

	printf ("\nCOMIENZO DE PRUEBAS MANEJADOR BITS.\n\n");
	
    prueba_ManejadorBits(ruta);
    
    printf("\n\nVolumen\n\n");
    
    prueba_ManejadorBits_volumen(ruta);
    printf("\nUnario\n");
	prueba_ManejadorBits_leer_unario(ruta);
	printf("\nBinario\n");
	
	prueba_ManejadorBits_leer_Binario (ruta);
	printf("\nGamma\n");
	prueba_ManejadorBits_leer_Gamma (ruta);
	printf("\nDelta\n");
	prueba_ManejadorBits_leer_Delta(ruta);
	
	printf("\nCadena\n");
	prueba_ManejadorBits_leer_Caracter(ruta);
	
	printf("\nPrueba Completa Lexico\n");
	prueba_ManejadorBits_leer_Lexico (ruta);
	
	printf ("\n\nFIN DE PRUEBAS MANEJADOR BITS.\n\n");
	
	
    return 0;
}




